package com.mark.common.utils;


import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mark.web.bill.exception.BillException;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: ECharts趋势图的工具类
 * @Author: Mark
 * @CreateDate: 2019/2/28 16:42
 * @Version: 2.0
 * @Copyright : 豆浆油条个人非正式工作室
 */
public class TrendChartUtil {

    private final static Map<String, String> MONTH_MAP = Maps.newHashMap();
    static {
        MONTH_MAP.put("01", "一月");
        MONTH_MAP.put("02", "二月");
        MONTH_MAP.put("03", "三月");
        MONTH_MAP.put("04", "四月");
        MONTH_MAP.put("05", "五月");
        MONTH_MAP.put("06", "六月");
        MONTH_MAP.put("07", "七月");
        MONTH_MAP.put("08", "八月");
        MONTH_MAP.put("09", "九月");
        MONTH_MAP.put("10", "十月");
        MONTH_MAP.put("11","十一月");
        MONTH_MAP.put("12", "十二月");
    }

    /**
     * 切割时间的单位指定为天
     */
    private static final String SPLIT_UNIT_DAY = "day";

    /**
     * 默认以天数分隔时间
     *
     * @param startDate ：开始时间
     * @param endDate   ：结束时间
     * @return ：安装天数分隔好的并且按照指定格式格式化后的时间字符列表
     */
    public static List<String> getDateList(Date startDate, Date endDate) {
        return getDateList(startDate, endDate, SPLIT_UNIT_DAY);
    }

    /**
     * 指定单位分隔时间
     *
     * @param startDate ：开始时间
     * @param endDate   ：结束时间
     * @param splitUnit ：分隔时间的单位
     * @return ：分隔好的并且按照指定格式格式化后的时间字符列表
     */
    public static List<String> getDateList(Date startDate, Date endDate, String splitUnit) {
        List<String> result = Lists.newArrayList();
        result.add(DateTimeUtil.dateToStr2(startDate));

        //以天数分隔时间：eg:startDate=2019-02-28，endDate=2019-03-02
        //得到的结果为：2019-02-28, 2019-03-01, 2019-03-02
        if (StringUtils.equals(splitUnit, SPLIT_UNIT_DAY)) {
            int dayBetween = DateTimeUtil.dayBetween(startDate, endDate);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            for (int i = 0; i < dayBetween; i++) {
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                Date date = calendar.getTime();
                String dateToStr2 = DateTimeUtil.dateToStr2(date);
                result.add(dateToStr2);
            }
        }
        return result;
    }

    /**
     * 获取趋势图的series的数据
     *
     * @param lineDateList  ：以天为单位分组查询到数据
     * @param xAxisDataList :XXXX年-XX月-XX日格式时间列表
     * @return ：
     */
    public static List<List<Double>> getSeriesDate(List<Map<String, Object>> lineDateList, List<String> xAxisDataList,LinkedHashSet<String> legendSet) {
        //参数校验
        List<String> expectKeySet = Arrays.asList("count", "type");
        lineDateList.forEach(map->{
            Set<String> keySet = map.keySet();
            if(keySet.size() != expectKeySet.size() || !keySet.containsAll(expectKeySet)){
                throw new BillException("输入数据列表中不含count或者type字段！");
            }
        });

        List<List<Double>> result = Lists.newArrayList();
        //补0
        List<Map<String, Object>> lineXAxisDate = addZeroToLineDateList(lineDateList, xAxisDataList);

        lineXAxisDate.forEach(map -> {
            String day = (String) map.get("type");
            String[] daySplit = day.split("-");
            map.put("year", daySplit[0]);
            map.put("month", daySplit[1]);
            map.put("day", daySplit[2]);
            legendSet.add(MONTH_MAP.get(daySplit[1]));
        });

        //根据"年份-月份"分组
        Map<String, List<Map<String, Object>>> collectMap = lineXAxisDate
                .stream()
                .collect(Collectors.groupingBy(e -> e.get("year").toString() + e.get("month").toString()));

        //map转treeMap保证结果根据key升序，即时间由小到大排序
        Map<String, List<Map<String, Object>>> collect = new TreeMap<>(collectMap);

        for (List<Map<String, Object>> list : collect.values()) {

            Double[] counts = new Double[31];
            for (int i = 0; i < 31; i++) {
                counts[i] = (double) 0;
            }
            list.forEach(map -> {
                String count =  map.get("count").toString();
                int day = Integer.parseInt(map.get("day").toString()) ;
                counts[day-1] = Double.valueOf(count);


            });
            result.add(Arrays.asList(counts));
        }
        return result;
    }

    private static List<Map<String, Object>> addZeroToLineDateList(List<Map<String, Object>> lineDateList, List<String> xAxisDataList) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (String day : xAxisDataList) {

            boolean lineDate = false;
            for (Map<String, Object> map : lineDateList) {
                String mapDay = (String) map.get("type");
                //查询数据库有该天的数据
                if (StringUtils.equals(mapDay, day)) {
                    result.add(map);
                    lineDate = true;
                    break;
                }
            }

            if (!lineDate) {
                Map<String, Object> addZeroMap = Maps.newHashMap();
                addZeroMap.put("type", day);
                addZeroMap.put("count", 0);
                result.add(addZeroMap);
            }
        }
        return result;
    }

    public static List<String> getDateList() {
        List<String> result = Lists.newArrayList();
        for (int i = 1; i <= 31; i++) {
            result.add(i + "号");
        }
        return result;
    }
}
